package com.opencee.common.utils;

import cn.hutool.extra.servlet.ServletUtil;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.MultipartResolver;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.Map.Entry;

/**
 * Http与Servlet工具类.
 *
 * @author liuyadu
 */
public class WebUtil extends ServletUtil {

    /**
     * 设置让浏览器弹出下载对话框的Header.
     *
     * @param fileName 下载后的文件名.
     */
    public static void setFileDownloadHeader(HttpServletResponse response, String fileName) {
        // 中文文件名支持
        String encoded = new String(fileName.getBytes(), StandardCharsets.ISO_8859_1);
        response.setHeader(HttpHeaders.CACHE_CONTROL, "no-cache, no-store, must-revalidate");
        response.setHeader(HttpHeaders.CONTENT_TYPE, "application/octet-stream");
        response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + encoded + "\"");
        response.setHeader(HttpHeaders.PRAGMA, "no-cache");
        response.setHeader(HttpHeaders.EXPIRES, "0");

    }

    /**
     * 获取当前请求参数
     *
     * @return
     */
    public static Map<String, String> getParameterMap() {
        return getParameterMap(getHttpServletRequest());
    }

    /**
     * 获取请求参数，并返回可读的Map
     * Get
     * application/x-www-form-urlencode
     * multipart/form-data
     *
     * @param request
     * @return
     */
    public static Map<String, String> getParameterMap(HttpServletRequest request) {
        String mediaType = request.getHeader(org.springframework.http.HttpHeaders.CONTENT_TYPE);
        Map<String, String> returnMap = new HashMap<>(8);
        if (StringUtils.isNotBlank(mediaType) && mediaType.contains(MediaType.MULTIPART_FORM_DATA_VALUE)) {
            // 文件上传表单
            MultipartResolver multipartResolver = SpringContextHolder.getBean(MultipartResolver.class);
            MultipartHttpServletRequest multiReq = multipartResolver.resolveMultipart(request);
            returnMap = conventParameterMap(multiReq.getParameterMap());
        } else {
            // 普通表单
            returnMap = conventParameterMap(request.getParameterMap());
        }
        // 参数Map
        return returnMap;
    }


    private static Map conventParameterMap(Map map) {
        Map<String, String> returnMap = new HashMap(8);
        // 返回值Map
        Iterator entries = map.entrySet().iterator();
        Entry entry;
        String name = "";
        String value = "";
        while (entries.hasNext()) {
            entry = (Entry) entries.next();
            name = (String) entry.getKey();
            Object valueObj = entry.getValue();
            if (null == valueObj) {
                value = "";
            } else if (valueObj instanceof String[]) {
                String[] values = (String[]) valueObj;
                if (values != null && values.length > 0) {
                    for (int i = 0; i < values.length; i++) {
                        value = values[i] + ",";
                    }
                    value = value.substring(0, value.length() - 1);
                }
            } else {
                value = valueObj.toString();
            }
            returnMap.put(name, value);
        }
        return returnMap;
    }

    /**
     * 判断是否响应json数据
     * 比如：Accept：text/xml（application/json）;
     * 代表客户端希望接受的数据类型是xml（json ）类型
     * Content-Type代表发送端（客户端|服务器）发送的实体数据的数据类型。
     * 比如：Content-Type：text/html（application/json） ;
     *
     * @param request
     * @return
     */
    public static boolean acceptHasJson(HttpServletRequest request) {
        String accept = request.getHeader(HttpHeaders.ACCEPT);
        if (StringUtils.isBlank(accept)) {
            return false;
        }
        return accept.contains(MediaType.APPLICATION_JSON_VALUE);
    }

    /**
     * 响应返回JSON字符串
     *
     * @param response
     * @param object
     * @return
     */
    public static void writeJson(HttpServletResponse response, Object object) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            writeJson(response, objectMapper.writeValueAsString(object), MediaType.APPLICATION_JSON_VALUE);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
    }

    /**
     * 响应返回字符串
     *
     * @param response
     * @param string
     * @return
     */
    public static void writeJson(HttpServletResponse response, String string, String type) {
        try {
            response.setContentType(type);
            response.setCharacterEncoding("utf-8");
            response.getWriter().print(string);
            response.getWriter().flush();
            response.getWriter().close();
        } catch (IOException e) {
        }
    }

    /**
     * 获取服务请求地址
     *
     * @param request
     * @return
     */
    public static String getServerUrl(HttpServletRequest request) {
        String url = request.getScheme() + "://" + request.getServerName()
                + ":" + request.getServerPort() + request.getContextPath();
        return url;
    }


    public static String getContextPath(HttpServletRequest request) {
        return request.getContextPath();
    }

    /**
     * 静态方法获取HttpServletRequest对象
     *
     * @return
     */
    public static HttpServletRequest getHttpServletRequest() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 静态方法HttpServletResponse对象
     *
     * @return
     */
    public static HttpServletResponse getHttpServletResponse() {
        try {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取请求头
     *
     * @param request
     * @return
     */
    public static Map<String, String> getHeaders(HttpServletRequest request) {
        Map<String, String> map = new LinkedHashMap<>();
        if (request != null) {
            Enumeration<String> enumeration = request.getHeaderNames();
            if (enumeration != null) {
                while (enumeration.hasMoreElements()) {
                    String key = enumeration.nextElement();
                    String value = request.getHeader(key);
                    map.put(key, value);
                }
            }
        }

        return map;
    }


    /**
     * url追加参数
     *
     * @param url   传入的url ex："http://www.baidu.com/index.html?id=16&a=16#/app/home"
     * @param name  参数名
     * @param value 参数值
     * @return
     * @author: xg.chen
     * @date:2016年9月2日
     */
    public static String addQuery(String url, String name, String value) {
        url += (url.indexOf('?') == -1 ? '?' : '&');
        url += name + '=' + value;
        return url;
    }

    /**
     * url追加参数
     *
     * @param url
     * @param map
     * @return
     */
    public static String addQuery(String url, Map<String, String> map) {
        Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, String> entry = it.next();
            url = addQuery(url, entry.getKey(), entry.getValue());
        }
        return url;
    }

    /**
     * 特殊字符转义
     *
     * @param value
     * @return
     */
    public static String cleanXSS(String value) {
        if (StringUtils.isNotEmpty(value)) {

        }
        return value;
    }

}
